﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using JigLibX.Collision;
using JigLibX.Physics;
using JigLibX.Geometry;
using JigLibX.Math;
using Microsoft.Xna.Framework.Graphics;
using JigLibX.Utils;

namespace DARE
{
    public class CPhysicHeightmap : APhysicObject
    {

    #region fields

        private CHeightMapInfo m_heightMapInfo;
        //private Vector3 m_pos;

    #endregion

    #region properties

        public CHeightMapInfo HeightMapInfo
        {
            get { return m_heightMapInfo; }
        }

        //internal Vector3 Pos
        //{
        //    get { return m_pos; }
        //}

    #endregion

    #region ctor

        public CPhysicHeightmap(CHeightMapInfo heightmapInfo)
        {
            Initialize(heightmapInfo, Vector3.Zero);
        }

        public CPhysicHeightmap(CHeightMapInfo heightmapInfo, Vector3 pos)
        {
            Initialize(heightmapInfo, pos);
        }

        private void Initialize(CHeightMapInfo heightmapInfo, Vector3 pos)
        {
            //m_pos = pos;

            //pos = new Vector3(25, -9.5f, -25);

            m_heightMapInfo = heightmapInfo;

            m_body = new Body();
            //m_collisionSkin = new CollisionSkin(null);
            m_collisionSkin = new CollisionSkin(m_body);
            m_body.CollisionSkin = m_collisionSkin;

            Array2D field = new Array2D(m_heightMapInfo.Width, m_heightMapInfo.Height);

            for (int x = 0; x < m_heightMapInfo.Width; ++x)
                for (int z = 0; z < m_heightMapInfo.Height; ++z)
                    field.SetAt(x, z, m_heightMapInfo.Heights[x, z] + pos.Y);

            m_collisionSkin.AddPrimitive(new Heightmap(field, pos.X, pos.Z, m_heightMapInfo.TerrainScale, m_heightMapInfo.TerrainScale), 
                new MaterialProperties(0.7f, 0.7f, 0.6f));
            // BUG !!! SHOULD TAKE THE POSITION !!!!
            //m_collisionSkin.ApplyLocalTransform(new Transform(

            //PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(m_collisionSkin);

            //Vector3 com = SetMass(1.0f);
            //m_collisionSkin.ApplyLocalTransform(new Transform(-com, Matrix.Identity));
            m_body.EnableBody();

            //PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.RemoveCollisionSkin(m_collisionSkin);

            if ((heightmapInfo.Height <= 128) && (heightmapInfo.Width <= 128))
                m_basicModel = new CHeightmapModel("mHeightmap", heightmapInfo);
            else
                Console.WriteLine("CPhysicHeightmap: Cannot create basicheightmap because HeightmapInfo.Height or Width > 128: " +
                    heightmapInfo.Height.ToString() + " " + heightmapInfo.Width.ToString());
        }

        ///// <summary>
        ///// Used to move the collision skin, very heavy because it recreate the the collision skin.
        ///// It is used when attached to an entity for example.
        ///// </summary>
        ///// <param name="pos"></param>
        //internal void SetPosition(Vector3 pos)
        //{
        //    m_pos = pos;

        //    Array2D field = new Array2D(m_heightMapInfo.Width, m_heightMapInfo.Height);

        //    for (int x = 0; x < m_heightMapInfo.Width; ++x)
        //        for (int z = 0; z < m_heightMapInfo.Height; ++z)
        //            field.SetAt(x, z, m_heightMapInfo.Heights[x, z] + pos.Y);

        //    m_body.DisableBody();

        //    PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.RemoveCollisionSkin(m_collisionSkin);
        //    m_collisionSkin.RemoveAllPrimitives();
        //    m_collisionSkin.AddPrimitive(new Heightmap(field, pos.X, pos.Z, m_heightMapInfo.TerrainScale, m_heightMapInfo.TerrainScale),
        //        new MaterialProperties(0.7f, 0.7f, 0.6f));
        //}

        public override APhysicObject Clone()
        {
            CPhysicHeightmap clone = new CPhysicHeightmap(m_heightMapInfo);

            base.CopyPropertiesTo(clone);
            return clone;
        }

    #endregion

    }
}
